
function getTextInfo(text, width, height, fontSize, space, lineHeight, overflow) {
    let len = text.length;
    let row = 0;
    let x = -space;
    let y = 0;
    let w = 0;
    let h = 0;
    lineHeight = Math.max(fontSize[1], lineHeight);
    let textInfo = [];
    let overflowFlag = false;
    for (let i = 0; i < len; i++) {
        if (text.charCodeAt(i) === 10) {//换行符
            row++;
            x = -space;
            y = 0;
            w = 0;
            h = 0;
            continue;
        } else if (text.charCodeAt(i) > 255) {
            if(x + w/2 + space + fontSize[0] > width) {//超出宽度，新增一行
                row++;
                x = -space;
                y = 0;
                w = 0;
                h = 0;
            }
            x += (w/2 + space + fontSize[0]/2);
            y = -lineHeight/2 - row * (lineHeight);
            w = fontSize[0];
            h = fontSize[1];
        } else {
            if(x + w/2 + space + fontSize[0]/2 > width) {//超出宽度，新增一行
                row++;
                x = -space;
                y = 0;
                w = 0;
                h = 0;
            }
            x += (w/2 + space + fontSize[0]/2/2);
            y = -lineHeight/2 - row * (lineHeight);
            w = fontSize[0] / 2;
            h = fontSize[1];
        }
        if(height !== 'auto' && lineHeight * (row + 1) > height) {//超出给定文字区域最大高度
            overflowFlag = true;
            if(overflow === 'hidden') {
                break;
            } else if(overflow === 'ellipsis') {
                let last3Letters = textInfo.slice(-3).reverse();
                last3Letters.forEach(item => {
                    if(width - item.x  < 3 * fontSize[0]/2) {
                        textInfo.pop()
                    }
                })
                x = textInfo[textInfo.length - 1].x + textInfo[textInfo.length - 1].w/2 + fontSize[0]/4;
                y = textInfo[textInfo.length - 1].y;
                w = fontSize[0]/2;
                h = fontSize[1];
                textInfo.push({ x, y, w, h, letter: '.' });
                textInfo.push({ x: x + fontSize[0]/2, y, w, h, letter: '.' });
                textInfo.push({ x: x + fontSize[0], y, w, h, letter: '.' });
                break;
            }
        }
        textInfo.push({ x, y, w, h, letter: text[i] });
    }
    row = overflowFlag ? row - 1: row;
    let textWidth = row === 0 ? textInfo[textInfo.length-1].x + textInfo[textInfo.length-1].w/2 : width;//不满一行
    let textHeight = height !== 'auto' 
    ? (textInfo.length > 0 ? lineHeight * (row + 1) : 0)
    : lineHeight * (row + 1);
    let containerWidth = width;
    let containerHeight = height !== 'auto' ? Math.max(textHeight, height) : textHeight;
    return {
        textWidth, 
        textHeight, 
        containerWidth,
        containerHeight,
        textInfo
    }

}
function getLocationOffset(containerWidth, containerHeight, horizontalLocation, verticalLocation) {
    let offsetX = 0;
    let offsetY = 0;
    switch(horizontalLocation) {
        case 'left':  
            offsetX = -containerWidth/2;
            break;
        case 'center':  
            offsetX = 0;
            break;
        case 'right':  
            offsetX = containerWidth/2;
            break;
        default:
            offsetX = 0;
    }
    switch(verticalLocation) {
        case 'bottom': 
            offsetY = containerHeight/2; 
            break;
        case 'middle':  
            offsetY = 0;
            break;
        case 'top':  
            offsetY = -containerHeight/2;
            break;
        default:
            offsetY = 0
    }
    return [offsetX, offsetY];
}
function getTextOffset(containerWidth, containerHeight, textWidth, textHeight, verticalAlign, textAlign) {
    let offsetX = 0;
    let offsetY = 0;
    switch(textAlign) {
        case 'left':  
            offsetX = -containerWidth/2;
            break;
        case 'center':  
            offsetX = -textWidth/2;
            break;
        case 'right':  
            offsetX = containerWidth/2-textWidth;
            break;
        default:
            offsetX = -textWidth/2;
    }
    switch(verticalAlign) {
        case 'top': 
            offsetY =  containerHeight/2; 
            break;
        case 'middle':  
            offsetY = textHeight/2;
            break;
        case 'bottom':  
            offsetY = -(containerHeight/2-textHeight);
            break;
        default:
            offsetY = textHeight/2;
    }
    return [offsetX, offsetY];
}
/**
 * @class
 * @memberof w.parser
 * @param {*} message 消息
 * @param {*} callback 处理完成的回调
 */
function text(message,callback){
    //  let id = Math.random()
    // console.time(id)
    let { data, color, fontInfo,horizontalLocation, verticalLocation, verticalAlign, textAlign, fontSize, space, width, height, overflow, lineHeight, varySize, pixelRatio } = message;
    let positions = [];
    let letterRelativePositions = [];
    let indices_array = [];
    let directions = [];
    let uvs = [];
    let colors = [];
    let sumIndex = 0;
    let letterCount = [];
    data.position.forEach((position, positionIndex) => {
        let text = data.text[positionIndex];
        let {textWidth, textHeight, containerWidth, containerHeight, textInfo} = getTextInfo(text, width, height, fontSize, space, lineHeight, overflow);
        let locationOffset = getLocationOffset(containerWidth, containerHeight, horizontalLocation, verticalLocation);
        let textOffset = getTextOffset(containerWidth, containerHeight,textWidth, textHeight, verticalAlign, textAlign);
        let offset = [locationOffset[0] + textOffset[0], locationOffset[1] + textOffset[1]]
        // console.log(textWidth, textHeight, textOffset)
        for (var index = 0; index < textInfo.length; index ++) {
            let letterInfo = textInfo[index];
            let letter = letterInfo.letter;
            if(!fontInfo.texture[letter]) {
                break;
            }
            positions.push(...position,...position,...position,...position);
            directions.push(
                -letterInfo.w/fontSize[0],letterInfo.h/fontSize[1],0,
                letterInfo.w/fontSize[0],letterInfo.h/fontSize[1],0,
                letterInfo.w/fontSize[0],-letterInfo.h/fontSize[1],0,
                -letterInfo.w/fontSize[0],-letterInfo.h/fontSize[1],0,
            );//左上，右上，右下，左下
            letterRelativePositions.push(
                letterInfo.x + offset[0], letterInfo.y + offset[1],
                letterInfo.x + offset[0], letterInfo.y + offset[1],
                letterInfo.x + offset[0], letterInfo.y + offset[1],
                letterInfo.x + offset[0], letterInfo.y + offset[1],
            )
            indices_array.push(sumIndex*4, sumIndex*4 + 2, sumIndex*4 + 1, sumIndex*4, sumIndex*4 +3, sumIndex*4 +2);
            
            let x = fontInfo.texture[letter].x / fontInfo.width,
                y = fontInfo.texture[letter].y / fontInfo.height,
                w = fontInfo.texture[letter].w / fontInfo.width,
                h = fontInfo.fontSize / fontInfo.height;
            uvs.push(x, y, x + w, y,  x + w, y + h, x, y + h);
            if(color.length) {
                if(color[4*index] !== undefined && color[4*index+1] !== undefined && color[4*index+2] !== undefined && color[4*index+3] !== undefined) {
                    colors.push(
                        color[4*index], color[4*index+1], color[4*index+2], color[4*index+3],
                        color[4*index], color[4*index+1], color[4*index+2], color[4*index+3],
                        color[4*index], color[4*index+1], color[4*index+2], color[4*index+3],
                        color[4*index], color[4*index+1], color[4*index+2], color[4*index+3]
                    );
                } else {
                    colors.push(
                        colors[colors.length-4], colors[colors.length-3], colors[colors.length-2], colors[colors.length-1],
                        colors[colors.length-4], colors[colors.length-3], colors[colors.length-2], colors[colors.length-1],
                        colors[colors.length-4], colors[colors.length-3], colors[colors.length-2], colors[colors.length-1],
                        colors[colors.length-4], colors[colors.length-3], colors[colors.length-2], colors[colors.length-1]
                    );
                }
            }
            sumIndex ++;
        }
        letterCount.push(textInfo.length)
    })
    positions = new Float32Array(positions);
    if(varySize) {
        letterRelativePositions = letterRelativePositions.map(item => item * pixelRatio)
    }
    letterRelativePositions = new Float32Array(letterRelativePositions);
    indices_array = new Uint32Array(indices_array);
    directions = new Float32Array(directions);
    colors = new Float32Array(colors);
    uvs = new Float32Array(uvs);
    // console.timeEnd(id)
    callback({data: {
        positions,
        offsets: letterRelativePositions,
        indices_array,
        directions,
        colors,
        uvs, 
    }, transferlist:[
        positions.buffer,
        letterRelativePositions.buffer,
        indices_array.buffer,
        directions.buffer,
        colors.buffer,
        uvs.buffer,
    ]});
}


export {text}